<?php
/**
 * Класс вспомогательных функций
 *
 * @author Александр Егоров <slamer@slamer.ru>
 * @author Дмитрий Кузьма <kouzma.d@slamer.ru>
 * @version 1.0
 */

class Service_Function {

	/**
	 * Делает из многомерного массива безопасную для сохранения строку чисел по столбцу
	 *
	 * @param string $glue - разделитель
	 * @param array $arrToBeEscaped - многомерный массив, из которого и будет формироваться строка
	 * @param string $strPartName - название столбца, по которому будут браться числа
	 * @return string - безопасная строка
	 */
	public static function intEscapeJoinOfPart(string $glue, array $arrToBeEscaped, $strPartName) {
		$sizeOfArr = sizeof($arrToBeEscaped);
		if (!$sizeOfArr) return '';
		$retStr= '';
		for ($i=0; $i < $sizeOfArr; $i++) {
			if ($i)
			  $retStr .= $glue . intval($arrToBeEscaped[$i][$strPartName]);
			else
			  $retStr .= intval($arrToBeEscaped[$i][$strPartName]);
		}
		return $retStr;
	}
	/**
	 * Возвращает безопасную для сохранения в БД строку из массива, состоящую из чисел
	 *
	 * @param string $glue - разделитель
	 * @param string $arrToBeEscaped - массив, которые следует преобразовать к безопасной строке
	 * @return string - безопасная строка
	 */
	public static function intEscapeJoin($glue, array $arrToBeEscaped) {
		$sizeOfArr = sizeof($arrToBeEscaped);
		if (!$sizeOfArr) return '';
		$retStr= '';
		for ($i=0; $i < $sizeOfArr; $i++) {
			if ($i)
			  $retStr .= $glue . intval($arrToBeEscaped[$i]);
			else
			  $retStr .= intval($arrToBeEscaped[$i]);
		}
		return $retStr;
	}
	/**
	 * Возвращает безопасную для сохранения в БД строку из массива (соединяются строки)
	 *
	 * @param string $glue - разделитель
	 * @param string $arrToBeEscaped - массив, которые следует преобразовать к безопасной строке
	 * @return string - безопасная строка
	 */
	public static function escapeJoin($glue, array $arrToBeEscaped) {
		$sizeOfArr = sizeof($arrToBeEscaped);
		if (!$sizeOfArr) return '';
		$retStr= '';

		for ($i=0; $i < $sizeOfArr; $i++) {
			if ($i)
			  $retStr .= $glue . self::escapeString($arrToBeEscaped[$i]);
			else
			  $retStr .= self::escapeString($arrToBeEscaped[$i]);
		}
		return $retStr;
	}
	/**
	 * Возвращает безопасную для сохранения в БД строку из массива (соединяются строки)
	 *
	 * @param string $glue - разделитель
	 * @param string $arrToBeEscaped - массив, которые следует преобразовать к безопасной строке
	 * @return string - безопасная строка
	 */
	public static function absolutelyEscapeJoin($glue, array $arrToBeEscaped) {
		$sizeOfArr = sizeof($arrToBeEscaped);
		if (!$sizeOfArr) return '';
		$retStr= '';

		for ($i=0; $i < $sizeOfArr; $i++) {
			if ($i)
			  $retStr .= $glue . Service_Function::absolutelyEscapeString($arrToBeEscaped[$i]);
			else
			  $retStr .= Service_Function::absolutelyEscapeString($arrToBeEscaped[$i]);
		}
		return $retStr;
	}


	/**
	 * Возвращает безопасную для сохранения в БД строку (в том числе преобразовывает и теги)
	 *
	 * @param string $toBeEscaped - строка, которую следует сделать безопасной
	 * @return string - безопасная строка
	 */
	public static function absolutelyEscapeString($toBeEscaped) {
		if (!get_magic_quotes_gpc() ) {//&& !get_magic_quotes_runtime()
			return mysql_escape_string(htmlspecialchars($toBeEscaped));
		}
	  else {
	    return str_replace("'", "&#39;", htmlspecialchars($toBeEscaped));
	  }
	}
	/**
	 * Возвращает безопасную для сохранения в БД строку (в том числе преобразовывает и теги)
	 *
	 * @param string $toBeEscaped - строка, которую следует сделать безопасной
	 * @return string - безопасная строка
	 */
	public static function escapeString($toBeEscaped) {
		if (!get_magic_quotes_gpc() ) {//&& !get_magic_quotes_runtime()
			return mysql_escape_string($toBeEscaped);
		}
	  else {
	    return $toBeEscaped;
	  }
	}

	/**
	 * Возвращает безопасный для сохранения в БД массив
	 *
	 * @param array $arrToBeEscaped - массив, который следует сделать безопасным
	 * @return string - безопасная строка
	 */
	public static function absolutelyEscapeArray($arrToBeEscaped) {
		if (empty($arrToBeEscaped)) return null;
	  foreach ($arrToBeEscaped as $key => $value) {
			if (is_array($value)) Service_Function::absolutelyEscapeArray($value);
			else $arrToBeEscaped[$key] = Service_Function::absolutelyEscapeString($value);
		}
		return $arrToBeEscaped;
	}
	/**
	 * Возвращает безопасный массив с целыми числами
	 *
	 * @param array $arrToBeEscaped - массив, который следует сделать безопасным
	 * @return array - "чистый" массив
	 */
	public static function intEscapeArray($arrToBeEscaped) {
		$sizeOfArr = sizeof($arrToBeEscaped);
		if (!$sizeOfArr) return '';
		for ($i=0; $i < $sizeOfArr; $i++) $arrToBeEscaped[$i] = intval($arrToBeEscaped[$i]);
		return $arrToBeEscaped;
	}

	/**
	 * Возвращает безопасную для сохранения в БД строку (без преобразования тегов)
	 *
	 * @param string $toBeEscaped - строка, которую следует сделать безопасной
	 * @return string - безопасная строка
	 */
	public static function absolutelyEscapeStringSavingHtml($toBeEscaped) {
	  if (!get_magic_quotes_gpc() && !get_magic_quotes_runtime()) {
	  	return mysql_escape_string($toBeEscaped);
	  }
	  else
	    //return $toBeEscaped;//addslashes($toBeEscaped);
	    return str_replace("'", "&#39;", $toBeEscaped);
	}

	/**
	 * Возвращает безопасную для сохранения в БД строку (с учетом обработки WYSYWYG редактором)
	 *
	 * @param string $toBeEscaped - строка, которую следует сделать безопасной
	 * @return string - безопасная строка
	 */
	public static function absolutelyEscapeStringFromWysiwyg($toBeEscaped) {
	    return self::absolutelyEscapeStringSavingHtml( Service_Editor::parseHTML($toBeEscaped) );
	}

	/**
	 * Возвращает строку, преобразованную к нормально отображаемому виду
	 *
	 * @param string $toBeUnescaped - строка, которую следует сделать привести к нормально отображаемому виду
	 * @return string - безопасная строка
	 */
	public static function unescapeString($toBeUnescaped) {
	  if (!get_magic_quotes_gpc() && !get_magic_quotes_runtime())
	    return stripslashes($toBeEscaped);
	  else
	    return stripslashes($toBeUnescaped);
	}
	/**
	 * Возвращает строку, преобразованную к нормально отображаемому виду
	 *
	 * @param string $toBeUnescaped - строка, которую следует сделать привести к нормально отображаемому виду
	 * @return string - безопасная строка
	 */
	public static function unescapeWysiwyg($toBeUnescaped) {
	    return str_replace('\"' , '"', $toBeUnescaped);
	}

	/**
	 * Возвращает строку, преобразованную к нормально отображаемому виду
	 *
	 * @param string $toBeUnescaped - строка, которую следует сделать привести к нормально отображаемому виду
	 * @return string - безопасная строка
	 */
	public static function unescapeQuot($toBeUnescaped) {
		//echo $toBeUnescaped;
		  $toBeUnescaped = str_replace('\"' , '"', $toBeUnescaped);
		  //echo $toBeUnescaped;
	    $toBeUnescaped = str_replace("\'" , "'", $toBeUnescaped);
	    //echo $toBeUnescaped;
	    return $toBeUnescaped;
	}
	/**
	 * Обрабочтчик непойманных исключений
	 * Выводит информацию о необработанных исключениях
	 *
	 * @param Exception $exception - необработанное исключение
	 */
	public static function exceptionHandler(Exception $exception) {
	  global $DOCUMENT_ROOT;
		//$objSession = User_Session::instance();
		//$userID = $objSession->getUserId();
	  if ($DOCUMENT_ROOT != '/home/sites/www.privateguide.com/web') {
			echo '<div class="programmError">';
		  echo '<strong>Uncaught exception</strong><br />';
		    echo 'Message: ' . $exception->getMessage() . '<br />';
		    echo 'File: <strong>' . $exception->getFile() . '</strong>, string <strong>' . $exception->getLine() . '</strong><br />';
		    $arrExceptionTrace = $exception->getTrace();
		    if (sizeof($arrExceptionTrace)) {
		      echo 'Chain:<br />';
		      for ($i = 0; $i < sizeof($arrExceptionTrace); $i++) {
		        echo '&nbsp;&nbsp;&nbsp;&nbsp;<strong>' . $arrExceptionTrace[$i]['file'] . '</strong>, string <strong>' . $arrExceptionTrace[$i]['line'] . '</strong>, function <strong>' . $arrExceptionTrace[$i]['function'] . '</strong>(';
		        for ($j = 0; $j < sizeof($arrExceptionTrace[$i]['args']); $j++) {
		        	if ($j != 0)
		        	  echo ', ';
		        	echo $arrExceptionTrace[$i]['args'][$j];
		        }
		        echo ')<br />';
		      }
		    }
		  echo '</div><br />';
		}
	  $logMsg = date("Y-m-d H:i:s") . ' Uncaught exception of the file ' . $exception->getFile() . ' (' . $exception->getLine() . '): ' . $exception->getMessage() . "\n";
	  $logErrType = 1;
	  error_log($logMsg, $logErrType, LOG);
	}

	/**
	 * Обработчик ошибок, предупреждений и пр.
	 * Выводит информацию о всевозможных ошибках
	 *
	 * @param integer $errType
	 * @param string $errMsg
	 * @param string $errFile
	 * @param integer $errLine
	 * @param array $errContext
	 */
	public static function errorHandler($errType, $errMsg, $errFile, $errLine, $errContext) {
	  switch ($errType) {
	    //E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING - эти ошибки нельзя обработать
	    case E_WARNING: case E_NOTICE: case E_CORE_WARNING: case E_USER_ERROR: case E_USER_WARNING: case E_USER_NOTICE: //Выводим все важные предупреждения в браузер, в лог-файл
		    global $DOCUMENT_ROOT;
				//$objSession = User_Session::instance();
				//$userID = $objSession->getUserId();
				if ($DOCUMENT_ROOT != '/home/sites/www.privateguide.com/web') {
					echo '<div class="programmError">';
		  	  echo '<strong>' . self::getExcteptionTypeName($errType) . '</strong><br />';
			    echo 'Message: ' . $errMsg . '<br />';
			    echo 'File: <strong>' . $errFile . '</strong>, String <strong>' . $errLine . '</strong><br />';
				  echo '</div><br />';
				}
		  case (E_NOTICE | E_USER_NOTICE):
	    default: //Выводим определенные и оставшиеся ошибки в лог-файл
	    	$logMsg = date("Y-m-d H:i:s") . ' Error ' . $errType . ' in the file ' . $errFile . ' (' . $errLine . '): ' . $errMsg . "\n";
		    $logErrType = 3;
	      error_log($logMsg, $logErrType, LOG);
		}
	}
	/**
	 * Выдает текстовое представление типа ошибки по его числовому эквиваленту
	 *
	 * @param integer $errType - числовой тип ошибки
	 * @return string - строковый тип ошибки
	 */
	public static function getExcteptionTypeName($errType) {
	  switch ($errType) {
	    case 1: return 'FATAL ERROR';
	    case 2: return 'WARNING';
	    case 4: return 'PARSE';
	    case 8: return 'NOTICE';
	    case 16: return 'CORE_ERROR';
	    case 32: return 'CORE_WARNING';
	    case 64: return 'COMPILE_ERROR';
	    case 128: return 'COMPILE_WARNING';
	    case 256: return 'USER_ERROR';
	    case 512: return 'USER_WARNING';
	    case 1024: return 'USER_NOTICE';
	    case 2048: return 'STRICT';
	  }
	}



	/**
	 * Преобразует строку из одной кодировки в другую
	 *
	 * @param string $str - строка для преобразования
	 * @param string $from - исходная кодировка строки
	 * @param string $to - выходная кодировка строки
	 * @return string - перекодированная строка
	 */
	public static function myConvertCharset($str, $from, $to) {
	  if (@function_exists('iconv')) {
	  	return iconv($from, $to, $str);
	  }
	  elseif (@function_exists('recode_string')) {
			return recode_string($from . '..'  . $to, $str);
	  }
	  else {
			print "function iconv not exists";
	    return $str;
	  }
	}

	/**
	 * Метод преобразует строку к нижнему регистру
	 *
	 * @param string $s
	 * @return string
	 */
	public static function strtolowerU($s) {
		//$t = "windows-1251";
		//$d = "utf-8";
		//return myConvertCharset(strtolower(myConvertCharset($s, $d, $t)), $t, $d);
	  return mb_strtolower($s, "utf-8");
	}

	/**
	 * Возвращает строку запроса url
	 *
	 * @return string - строка запроса
	 */
  public static function getCurrentUrl() {
		global $QUERY_STRING;
		global $PHP_SELF;
		if ($QUERY_STRING != '')
		  return $PHP_SELF  . '?' . $QUERY_STRING;
		else
			return $PHP_SELF;
	}

	/**
	 * Возвращает строку запроса url, но без части идущей за знаком "?"
	 *
	 * @return string
	 */
	public static function getCurrentSmallUrl() {
		global $PHP_SELF;
		return $PHP_SELF;
	}

	/**
	 * Enter description here...
	 *
	 * @param int $value - текущее значение
	 * @param int $min - минимальное
	 * @param int $middle - среднее
	 * @param int $max - максимальное
	 */
	public static function getColor($value, $min, $middle, $max) {
		if ($value >= $max) return 'ff00';
		if ($value <= $min) return '00ff';
		if ($value > $middle) {
			 $val = $value - $middle;
			 $red = 128 + ceil($val / ($max - $middle) * 128);
			 $green = 256 - $red;
		}
		else {
			 $val = $middle - $value;
			 $green = 128 + ceil($val / ($middle - $min) * 128);
			 $red = 256 - $green;
		}
		return dechex($red) . dechex($green);
	}

	/**
	 * Получает то что находится в cuttext строки (cuttext="..." - возвращает ...)
	 *
	 * @param string $content - строка для поиска
	 * @param string $paramName - не используется
	 * @return string
	 */
	public static function getUniqueTextParamFirst($content, $paramName) {
	    $paramStartPos = strpos($content, 'cuttext="') + 9;
	    $paramEndPos = strpos($content, '"', $paramStartPos);
	    if (is_integer($paramStartPos) && is_integer($paramEndPos))
	      return substr($content, $paramStartPos, $paramEndPos - $paramStartPos);
	    else
	      return '';
	}
	/**
	 * Метод возвращает содержимое некоторого HTML тега
	 *
	 * @param string $str - строка для поиска
	 * @param string $tag - искомый тег
	 * @return string
	 */
	public static function getTagBetweenValueFirst($str, $tag) {
	  $start = strpos($str, $tag);
	  $finish = findEndOfTag($str, $tag, $start);
	  $str = substr($str, $start - 1, ($finish - $start) + 2);
	  $str = substr($str, strpos($str, ">") + 1);
	  return substr($str, 0, strlen($str) - strlen('</' . $tag . '>'));
	}

	/**
	 * Получает длину строки с учетом того, что некоторые символы занимают 2 байта
	 *
	 * @param string $s
	 * @return int
	 */
	public static function utf8_strlen($s) {
    return preg_match_all('/./u', $s, $tmp);
	}

	/**
	 * Возвращает подстроку с учетом тго, что в utf8  некоторые символы занимают 2 байта
	 *
	 * @param string $s
	 * @param int $offset
	 * @param int $len
	 * @return string
	 */
	public static function utf8_substr($s, $offset, $len = 'all') {
    if ($offset<0) $offset = utf8_strlen($s) + $offset;
    if ($len!='all') {
      if ($len<0) $len = utf8_strlen($s) - $offset + $len;
      $xlen = self::utf8_strlen($s) - $offset;
      $len = ($len>$xlen) ? $xlen : $len;
      preg_match('/^.{' . $offset . '}(.{0,'.$len.'})/us', $s, $tmp);
    }
    else {
      preg_match('/^.{' . $offset . '}(.*)/us', $s, $tmp);
    }
    return (isset($tmp[1])) ? $tmp[1] : false;
	}
	/**
	 * Метод находин конец тега, с учетом вложенности
	 *
	 * @param string $htmlString
	 * @param string $tagName
	 * @param integer $startPosition
	 */
	public static function findEndOfTag($htmlString, $tagName, $startPosition, $k = 1) {
		//echo 'оставшаяся строка:' . htmlspecialchars(substr($htmlString, $startPosition)) .'<br/>';
		//echo '!' . $k;
		$tagNameLength = strlen($tagName);
		$closePosition = $openPosition = $startPosition;
		for (; $k > 0; $k--) {
			$closePosition = strpos( $htmlString, '</' . $tagName, $closePosition);
			if ($closePosition === false)
			  return false;
			$closePosition = strpos( $htmlString, '>', $closePosition);
		}
		//echo '<br /><br />';
		//echo 'Закрылись до' . $k;

		while (true) {
			$openPosition = strpos( $htmlString, '<' . $tagName, $openPosition);
			if ($openPosition === false)
			  break;
			$openPosition = strpos( $htmlString, '>', $openPosition);
			if ($openPosition < $closePosition)
			  $k++;
			else
			  break;
		  if ($k == 100)
		    break;
		}

		if ($k == 0)
		  return $closePosition;
		else
		  return findEndOfTag($htmlString, $tagName, $closePosition + 1, $k);
	}

	/**
	 * Метод возвращает подстроку с троеточием на конце, если длина исходной строки меньше подстроки. В противном случае возвращает исходную строку
	 *
	 * @param string $str
	 * @param int $limit
	 * @return string
	 */
	public static function utf8_string_with_limit($str, $limit) {
		if (self::utf8_strlen($str) <= $limit+1)
		  return $str;
		else
		  return self::utf8_substr($str, 0, $limit) . '...';
	}

	/**
	 * Возвращает строку с заглавной перовой буквой с учетом того, что в utf8  некоторые символы занимают 2 байта
	 *
	 * @param string $s
	 * @param int $offset
	 * @param int $len
	 * @return string
	 */
	public static function utf8_first_to_upper($s)
	{
		$first = self::utf8_substr($s, 0, 1);
		$last = self::utf8_substr($s, 1);
    return mb_strtoupper($first, "utf-8") . $last;
	}

	/**
	 * Возвращает первую букву строки, делая её заглавной, с учетом того, что в utf8  некоторые символы занимают 2 байта
	 *
	 * @param string $s
	 * @return string
	 */
	public static function utf8_first_upper_letter($s)
	{
		$first = self::utf8_substr($s, 0, 1);
    //return mb_strtoupper($first, "utf-8");
    return $first;
	}
  
	/**
	 * Возвращает строку со строчной перовой буквой с учетом того, что в utf8  некоторые символы занимают 2 байта
	 *
	 * @param string $s
	 * @param int $offset
	 * @param int $len
	 * @return string
	 */
	public static function utf8_first_to_lower($s)
	{
		$first = self::utf8_substr($s, 0, 1);
		$last = self::utf8_substr($s, 1);
    return mb_strtolower($first, "utf-8") . $last;
	}
	/**
	 * Метод получает уникальные элементы просто (линейного) массива
	 *
	 * @param unknown_type $arrIn
	 * @return unknown
	 */
	public static function getUniqueElementsOfSimpleArray($arrIn) {
		if (!$arrIn) return null;
		$arrOut = array();
		$arrOut[0] = $arrIn[0];
		$inSize = sizeof($arrIn);
		for ($i = 0; $i < $inSize; $i++) {
		  for ($j = 0; $j < sizeof($arrOut); $j++) {
		    if ($arrOut[$j] == $arrIn[$i]) break;
		  }
		  if ($j == sizeof($arrOut)) $arrOut[] = $arrIn[$i];
		}
		return $arrOut;
	}

	/**
	 * Метод возвращает текст, очищенный от html
	 *
	 * @param string $textWithHtml
	 * @return string
	 */
	/*public static function getTextWithoutHtml($textWithHtml) {
		$retText  = '';
		$closeTagPos = -1;
		$openTagPos = strpos($textWithHtml, '<');
		if ($openTagPos === false) return $textWithHtml; // Если совпадений не найдено
		do {
			$retText .= substr($textWithHtml, $closeTagPos + 1, $openTagPos - $closeTagPos - 1);
			//$closeTagPos = strpos($textWithHtml, '<', $openTagPos);
		} while ($openTagPos !== false);
		return $retText;
	}*/
	/**
	 * Метод возвращает часть HTML кода, закрывая открытые теги
	 *
	 * @param string $textWithHtml
	 * @param integer $limitOfNoneHtml
	 * @return string
	 */
	public static function getPartOfHtmlText($textWithHtml, $limitOfNoneHtml = 250) {
		if (self::utf8_strlen($textWithHtml) <= $limitOfNoneHtml) return $textWithHtml;
		$currentTextLength = 0;
		//$arrOpenTags = array();

		$retText  = '';
		$openTagPos = strpos($textWithHtml, '<');
		$closeTagPos = -1;
		if ($openTagPos === false) return $textWithHtml; // Если это голый текст без html
		while ($openTagPos !== false) {
			/*
			$firstLetterOfTag = substr($textWithHtml, $openTagPos + 1, 1);
			if ($firstLetterOfTag == '/') { //закрывающий тег

			}
			*/
			if ($openTagPos > $closeTagPos + 1) {
				$partOfText = substr($textWithHtml, $closeTagPos + 1, $openTagPos - $closeTagPos - 1);
				$partOfTextLength = self::utf8_strlen($partOfText);
				if ($currentTextLength + $partOfTextLength < $limitOfNoneHtml) {
					$currentTextLength += $partOfTextLength;
					$tagSpacePos = strpos($textWithHtml, ' ', $openTagPos);
				}
				else { // Дошли до нужного количества символов
					$retText = substr($textWithHtml, 0, $closeTagPos + 1);
					$partOfText = self::utf8_substr($textWithHtml, $closeTagPos + 1, $limitOfNoneHtml - $currentTextLength);
					$firstSpaceBeforeEnd = strrpos($partOfText, ' ');
					//echo $limitOfNoneHtml . '!' . $currentTextLength  . '!' .  $partOfTextLength;
					//$retText .= self::utf8_substr($textWithHtml, $closeTagPos + 1, $limitOfNoneHtml - $currentTextLength);
					$retText .= substr($partOfText, 0, $firstSpaceBeforeEnd);
					return $retText;
				}
			}
			$closeTagPos = strpos($textWithHtml, '>', $openTagPos);
			if ($closeTagPos === false) return $textWithHtml; // Один из тегов не закрыт
			$openTagPos = strpos($textWithHtml, '>', $closeTagPos);
		}
		$retText = substr($textWithHtml, 0, $closeTagPos + 1);
		$partOfText = self::utf8_substr($textWithHtml, $closeTagPos + 1, $limitOfNoneHtml - $currentTextLength);
		$firstSpaceBeforeEnd = strrpos($partOfText, ' ');
		//$retText .= self::utf8_substr($textWithHtml, $closeTagPos + 1, $limitOfNoneHtml - $currentTextLength);
		$retText .= substr($partOfText, 0, $firstSpaceBeforeEnd);
		return $retText;
	}

	/**
	 * Метод закрывает открытые html-теги
	 *
	 * @param string $textWithHtml
	 * @return string
	 */
	/*public static function closeTags($textWithHtml) {
		$arrOpenTags = array();
		$openTagPos = strpos($textWithHtml, '<');
		while ($openTagPos !== false) {
			$isCloseTag = ($textWithHtml{$openTagPos + 1} == '/'); //Проверяем, закрывающие это тег или нет
			$deltaForName = $isCloseTag ? 2 : 1;
			$spaseTagPos = strpos($textWithHtml, ' ', $openTagPos + $deltaForName);
			$tagName = substr($textWithHtml, $openTagPos + $deltaForName, $spaseTagPos - $deltaForName);
			$closeTagPos = strpos($textWithHtml, ' ', $spaseTagPos + 1);
			if ($textWithHtml{$closeTagPos - 1} == '/') continue; // Если это самозакрывающийся тег
			if ($isCloseTag) {
				if (end($arrOpenTags) == $tagName) array_pop($arrOpenTags);
			}
			else $arrOpenTags[] = $tagName;

		}
	}*/

	/**
	 * Метод закрывает открытые html-теги
	 *
	 * @param string $textWithHtml
	 * @return string
	 */
	public static function closetags($text)	{
		// Выбираем абсолютно все теги
	 	if (preg_match_all("/<([\/]?)([\w\d]+)[^>\/]*>/iU", $text, $matches, PREG_SET_ORDER)) {
	  	$stack = array();
	  	foreach ($matches as $k => $match) {
	   		$tag = strtolower($match[2]);
	   		if (!$match[1]) {
	    		// если тег открывается добавляем в стек
	    		$stack[] = $tag;
	   		}
	   		elseif (end($stack) == $tag) {
	    		// если тег закрывается, удаляем из стека
	    		array_pop($stack);
	   		}
	   		else {
	    		// если это закрывающий тег, который не открыт, открываем
	    		$text = '<'.$tag.'>'.$text;
	   		}
	  	}
	  	while ($tag = array_pop($stack)) {
	  		// закрываем все открытые теги
	   		$text .= '</'.$tag.'>';
	  	}
	 	}
	 	return $text;
	}

	public static function replaceQuotes($str) {
	  return str_replace("'", "&#39;", str_replace("\"", "&quot;", $str));
	}

  public static function strlenUnicode($str) {
    return strlen(iconv("UTF-8", "WINDOWS-1251", $str));
  }

  /**
   * Обрезает строку по последему пробелу и дописывает многоточие
   *
   * @return string
   */
  public static function cutString($str, $charAmount) {
    $str = iconv("UTF-8", "WINDOWS-1251", $str);
    if (strlen($str) > $charAmount) {
      $str = substr($str, 0, $charAmount+1);
      do {
        $sym = substr($str, -1, 1);
        $str = substr($str, 0, strlen($str)-1);
      } while ($sym != ' ' && strlen($str) > 10);
      $str .= '...';
    }
    $str = iconv("WINDOWS-1251", "UTF-8", $str);
    return $str;
  }

  /**
   * Обрезает строку по последему пробелу и дописывает многоточие
   *
   * @return string
   */
  public static function getUrlWithGetParamsByArray($url, $arrParams) {
  	$i = 0;
  	$params = '';
		foreach($arrParams as $var => $val) {
			if ($i) $params .= '&';
			$params .= $var . '=' . $val;
			$i++;
		}
		return $url . '?' . $params;
  }

	public static function getFacebookCookie($app_id, $application_secret) {
		if (isset($_COOKIE['fbs_' . $app_id])) {
		  $args = array();
		  parse_str(trim($_COOKIE['fbs_' . $app_id], '\\"'), $args);
		  ksort($args);
		  $payload = '';
		  foreach ($args as $key => $value) {
		    if ($key != 'sig') {
		      $payload .= $key . '=' . $value;
		    }
		  }
		  if (md5($payload . $application_secret) != $args['sig']) {
		    return null;
		  }
		  setcookie('fbs_' . $app_id, null, -1, W_ABSPATH);
		  return $args;
		}
		else return array();
	}
	
	
	public static function translit($str) {
	  $ruEn = array('а'=>'a','б'=>'b','в'=>'v','г'=>'g','д'=>'d','е'=>'e','ё'=>'yo','ж'=>'j','з'=>'z','и'=>'i','й'=>'i','к'=>'k','л'=>'l','м'=>'m','н'=>'n','о'=>'o','п'=>'p','р'=>'r','с'=>'s','т'=>'t','у'=>'u','ф'=>'f','х'=>'h','ц'=>'c','ч'=>'ch','ш'=>'sh','щ'=>'sch','ъ'=>'_','ы'=>'y','ь'=>'_','э'=>'e','ю'=>'yu','я'=>'ya');
	  return strtr($str, $ruEn);
	  
	}
}
?>